<template>
  <el-container>
    <splitpanes class="default-theme" @resize="resizeEvent">
      <pane size="20" class="" style="background-color: white">
        <el-row class="widget-group">
          <div class="group-title">基础组件</div>
          <div class="group-widget-list">
            <div
              v-for="item in compoentList"
              :key="item.id"
              @drag="drag(item)"
              @dragend="dragend"
              class="group-widget-item"
              draggable="true"
              unselectable="on"
            >
              <div class="icon">
                <el-icon><component :is="item.iconName"></component></el-icon>
              </div>
              <div class="name">{{ item.name }}</div>
            </div>
          </div>
        </el-row>
      </pane>
      <pane size="60">
        <el-main style="padding: 0px; overflow: hidden; position: relative">
          <el-card style="height: 65px">
            <template #header>
              <div style="float: right">
                <el-button @click="back">返 回</el-button>
                <el-button @click="save" type="primary">提 交</el-button>
              </div>
            </template>
          </el-card>

          <el-card class="draw">
            <el-scrollbar :height="height">
              <div
                id="content"
                @dragenter="dragenter"
                @dragleave="dragleave"
                :style="{ height: height + 'px' }"
              >
                <grid-layout
                  id="layout"
                  style="height: 100%"
                  ref="gridlayout"
                  v-model:layout="layout"
                  :col-num="12"
                  :row-height="30"
                  :is-draggable="true"
                  :is-resizable="true"
                  :vertical-compact="true"
                >
                  <grid-item
                    ref="gridItemRefs"
                    :key="item.i"
                    v-for="(item, index) in layout"
                    @click="getSetting(item)"
                    :x="item.x"
                    :y="item.y"
                    :w="item.w"
                    :h="item.h"
                    :i="item.i"
                    @resize="resizeGridItem(index, $event)"
                  >
                    <span class="close"
                      ><el-icon @click.stop="delItem(item)"><Close /></el-icon
                    ></span>
                    <template v-if="'container' === item.category">
                      <component
                        ref="fieldRef"
                        :is="getFieldWidget(item)"
                        v-model:widget="layout[index]"
                        :fileName="fileName"
                        v-model:setting="setting"
                        @dragSubForm="dragSubForm"
                        @dragLeaveSubForm="dragLeaveSubForm"
                      ></component>
                    </template>
                    <template v-else>
                      <component
                        ref="fieldRef"
                        :is="getFieldWidget(item)"
                        :widget="item.config"
                        :fileName="fileName"
                        @getData="getAllData"
                      ></component>
                    </template>
                  </grid-item>
                </grid-layout>
              </div>
            </el-scrollbar>
          </el-card>
        </el-main>
      </pane>
      <pane size="20">
        <el-scrollbar :height="height + 95">
          <el-card>
            <component
              v-if="setting"
              :is="getSettingWidget()"
              v-model="setting"
              :configData="configData"
              :fileName="fileName"
            ></component>
          </el-card>
        </el-scrollbar>
      </pane>
    </splitpanes>
  </el-container>
</template>
<script>
//局部批量注册组件
const requireAll = require.context("./components/", true, /\.vue$/);
const componentsObj = {};
let arr = [];
const modulList = requireAll.keys().map((item) => requireAll(item));
modulList.forEach(({ default: modulObj }) => {
  componentsObj[modulObj.__name] = modulObj;
  arr.push(modulObj.__name);
});
export default {
  components: componentsObj, //注册所有相关组件
  data() {
    return {
      comList: arr,
    };
  },
};
</script>

<script setup>
import { ref, onMounted, getCurrentInstance, nextTick, onUnmounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import { Close, Plus, Grid } from "@element-plus/icons-vue";
import { ElMessage, ElNotification } from "element-plus";
import { deepClone } from "@/utils/arr";
import tool from "@/utils/tool";
import API from "@/api/model/meta";
import useTabs from "@/utils/useTabs";
import compoentList from './index.js'
const route = useRoute();
const router = useRouter();
const setting = ref();

const configType = ref();
const gridlayout = ref(null);
const fileName = ref();
const gridItemRefs = ref([]);
const fieldRef = ref(null);
const layout = ref([]);
const dragLayout = ref([]);
const dragArrRef = ref();
const dragTarget = ref();
const configData = ref({});
let DragPos = {}; //拖拽对象
let colNum = 12;
let height;
let mouseXY = { x: null, y: null }; //拖拽位置
let parentRect = {}; //拖拽放下目标dom
let enterMainForm = true;
onMounted(() => {
  document.addEventListener("dragover", getHW);
  height = tool.data.get("windowHeight") - 90;
  getInit();
});
onUnmounted(() => {
  document.removeEventListener("dragover", getHW);
});
function getHW(e) {
  e.preventDefault();
  nextTick(() => {
    mouseXY.x = e.clientX;
    mouseXY.y = e.clientY;
  });
}
const getInit = async () => {
  let res = await API.blockDesigner.readBlocksFile.post({ id: route.query.id });
  if (res.code == "200") {
    configData.value = res.configData;
    console.log(res.configData)
    if (res.fileContent) {
      layout.value = JSON.parse(res.fileContent);
      dragLayout.value = layout.value;
      dragArrRef.value = gridItemRefs.value;
      dragTarget.value = gridlayout.value;
    }
    fileName.value = res.reportFileName;
  }
  parentRect = document.getElementById("content").getBoundingClientRect();
};
const drop = (e) => {
  console.log(e);
};
const dragenter = (e) => {
  if (enterMainForm) {
    nextTick(() => {
      dragLayout.value = layout.value;
      dragArrRef.value = gridItemRefs.value;
      dragTarget.value = gridlayout.value;
      parentRect = document.getElementById("content").getBoundingClientRect();
    });
  }
};
const dragleave = (e) => {};
const dragSubForm = (val) => {
  enterMainForm = false;
  let index = dragLayout.value.findIndex((obj) => obj.i === "drop");
  if (index !== -1) {
    dragTarget.value.emitter.all.get("dragEvent")[0]([
      "dragend",
      "drop",
      1,
      1,
      1,
      1,
    ]);
    dragLayout.value.splice(index, 1);
  }
  nextTick(() => {
    parentRect = val.position;
    let subForm = layout.value.find((ele) => ele.i === val.subId);
    dragLayout.value = subForm.config.tabs.find(
      (ele) => subForm.config.selected === ele.name
    ).children;
    dragArrRef.value = val.gridItem;
    dragTarget.value = val.gridlayout;
  });
};
const dragLeaveSubForm = (target) => {
  enterMainForm = true;
  if (target === document.getElementById("layout")) {
    let index = dragLayout.value.findIndex((obj) => obj.i === "drop");
    if (index !== -1) {
      dragTarget.value.emitter.all.get("dragEvent")[0]([
        "dragend",
        "drop",
        1,
        1,
        1,
        1,
      ]);
      dragLayout.value.splice(index, 1);
    }
    dragLayout.value = layout.value;
    dragArrRef.value = gridItemRefs.value;
    dragTarget.value = gridlayout.value;
    parentRect = document.getElementById("content").getBoundingClientRect();
    dragenter();
  }
};
function drag(item) {
  let mouseInGrid = false;
  if (
    mouseXY.x > parentRect.left &&
    mouseXY.x < parentRect.right &&
    mouseXY.y > parentRect.top &&
    mouseXY.y < parentRect.bottom
  ) {
    mouseInGrid = true;
  }
  if (
    mouseInGrid === true &&
    dragLayout.value.findIndex((item) => item.i === "drop") === -1
  ) {
    dragLayout.value.push({
      x: (dragLayout.value.length * 2) % (colNum || 12),
      y: dragLayout.value.length + (colNum || 12), // puts it at the bottom
      w: item.w,
      h: item.h,
      i: "drop",
    });
  }
  let index = dragLayout.value.findIndex((item) => item.i === "drop");
  if (index !== -1) {
    try {
      dragArrRef.value[dragLayout.value.length].style.display = "none";
    } catch (error){
      console.log(error)
    }
    let el = dragArrRef.value[index];
    let new_pos = {};
    if (mouseInGrid === true && el) {
      el.dragging = {
        top: mouseXY.y - parentRect.top,
        left: mouseXY.x - parentRect.left,
      };
      new_pos = el.calcXY(
        mouseXY.y - parentRect.top,
        mouseXY.x - parentRect.left
      );
      dragTarget.value.dragEvent([
        "dragstart",
        "drop",
        new_pos.x,
        new_pos.y,
        item.h,
        item.w,
      ]);
      DragPos = deepClone(item);
      DragPos.x = dragLayout.value[index].x;
      DragPos.y = dragLayout.value[index].y;
    }
    if (mouseInGrid === false) {
      dragTarget.value.emitter.all.get("dragEvent")[0]([
        "dragend",
        "drop",
        new_pos.x,
        new_pos.y,
        item.h,
        item.w,
      ]);
      for (let i = 0; i < dragLayout.value.length; i++) {
        if (dragLayout.value[i].i === "drop") {
          dragLayout.value.splice(i, 1);
        }
      }
      // let index = dragLayout.value.findIndex((obj) => obj.i === "drop");
      // if (index !== -1) {
      //   dragLayout.value.splice(index, 1);
      // }
    }
  }
}
function dragend(e) {
  let index = dragLayout.value.findIndex((obj) => obj.i === "drop");
  if (index !== -1) {
    dragLayout.value.splice(index, 1);
  }
    var now = new Date();
    DragPos.i = now.getTime();
  let mouseInGrid = false;
  if (
    mouseXY.x > parentRect.left &&
    mouseXY.x < parentRect.right &&
    mouseXY.y > parentRect.top &&
    mouseXY.y < parentRect.bottom
  ) {
    mouseInGrid = true;
    mouseXY = { x: null, y: null };
  }
  if (mouseInGrid === true) {
    dragLayout.value.push(DragPos);
    dragTarget.value.emitter.all.get("dragEvent")[0]([
      "dragend",
      "drop",
      DragPos.x,
      DragPos.y,
      1,
      1,
    ]);
  }
}
// }
const delItem = (item) => {
  let delIndex = layout.value.findIndex((el) => el.i === item.i);
  layout.value.splice(delIndex, 1);
};
const getFieldWidget = (item) => {
  if (item.type) {
    return item.type + "-widget";
  }
};
const getSettingWidget = (item) => {
  return setting.value.type + "-setting";
};
const getSetting = (val) => {
  setting.value = val;
};
const resizeGridItem = (index) => {
  // if(fieldRef.value[index].handleResize){
  //   fieldRef.value[index].handleResize()
  // }
};
const resizeEvent = () => {
  // echartsKey.value+=1
};
const getAllData = (val) => {
  fieldRef.value.forEach((ele) => {
    if (ele.changeOption) {
      ele.changeOption(val);
    }
    else if (ele.getTableData) {
      ele.getTableData(val);
    }
    else if(ele.getAllData){
      ele.getAllData(val)
    }
  });
};
const back = () => {
  useTabs.close();
  router.back();
};
const save = async () => {
  let res = await API.blockDesigner.saveBlocksFile.post({
    metaTemplateId: route.query.id,
    fileContent: JSON.stringify(layout.value),
  });
  if (res.code == "200") {
    ElNotification.success({ message: "保存成功" });
  }
};
defineExpose({
  drag,
  dragend,
});
</script>

<style lang="less" scoped>
.draw {
  :deep(.el-card__body) {
    background-clip: content-box;
    // background-color: #eee;
  }
}

.close {
  height: 16px;
  width: 16px;
  position: absolute;
  top: 0px;
  right: 0px;
  cursor: pointer;
  color: #000000;
  z-index: 9;
}
.item-list {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
.item {
  display: flex;
  justify-content: center;
  cursor: move;
  float: left;
  background: #fff;
  width: 50%;
  height: 40px;
  line-height: 40px;
  text-align: center;
  margin: 10px 15px 15px 0;
  border: 1px solid #e6e6e6;
}
.widget-group .group-title {
  font-weight: 700;
  color: #333;
  height: 45px;
  line-height: 45px;
}

.widget-group .group-widget-list {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}

.widget-group .group-widget-list .group-widget-item {
  margin-bottom: 10px;
}

.widget-group .group-widget-list .group-widget-item .icon {
  font-size: 26px;
  text-align: center;
  width: 64px;

  color: #666;
  cursor: pointer;
  line-height: 64px;
  border-radius: 4px;
  border: 1px solid #e8e8e8;
}
.widget-group .group-widget-list .group-widget-item .icon:hover {
  background: #f6f7f9;
}
.widget-group .group-widget-list .group-widget-item .name {
  width: 64px;
  height: 26px;
  line-height: 26px;
  text-align: center;
  font-size: 12px;
  font-weight: 400;
  color: #666;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vue-grid-layout {
  background: #eee;
}

.vue-grid-item:not(.vue-grid-placeholder) {
  background: white;
  /* border: 1px solid black; */
}

.vue-grid-item .resizing {
  opacity: 0.9;
}

.vue-grid-item .static {
  background: #cce;
}

.vue-grid-item .text {
  font-size: 24px;
  text-align: center;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  height: 100%;
  width: 100%;
}

.vue-grid-item .no-drag {
  height: 100%;
  width: 100%;
}

.vue-grid-item .minMax {
  font-size: 12px;
}

.vue-grid-item .add {
  cursor: pointer;
}

.vue-draggable-handle {
  position: absolute;
  width: 30px;
  height: 30px;
  top: 0;
  left: 0;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>")
    no-repeat;
  background-position: bottom right;
  padding: 0 8px 8px 0;
  background-repeat: no-repeat;
  background-origin: content-box;
  box-sizing: border-box;
  cursor: pointer;
  z-index: 9;
}

.layoutJSON {
  background: #ddd;
  border: 1px solid black;
  margin-top: 10px;
  padding: 10px;
}

.layoutJSON {
  background: #ddd;
  border: 1px solid black;
  margin-top: 10px;
  padding: 10px;
}

.columns {
  -moz-columns: 120px;
  -webkit-columns: 120px;
  columns: 120px;
}
.stopDrag * {
  pointer-events: none;
}
</style>